# -*- coding: utf-8 -*-

# -------------------------------
# Author    : linlingwei
# Email     : 951035650@qq.com
# File Name : fTemplate.py
# Date      : 2019/8/23 
# IDE       : PyCharm
# Version   : 1.0.1
# -------------------------------

import maya.cmds as mc
import maya.mel as mel

import configs.constants.facial_constant as fc
import configs.constants.global_constant as gc
import configs.constants.suffix_constant as sc
import configs.constants.nodeType_constant as ntc
import configs.constants.attribute_constant as ac

import scripts.commonCmds as con
reload(con)

import rig.facial.fCore as fCore
reload(fCore)

class FacialTemplate(fCore.FacialCore):
    def __init__(self,tag=""):
        super(FacialTemplate,self).__init__(tag)
        self.transform_init()
    
    def jloc(self,name,colorId=None,scale=0.1,crv = None,parameter=0,maxValue=100,top=True):
        
        jot = mc.createNode(ntc.tJoint,name=name)
        loc = mc.createNode(ntc.tLocator,name=jot+"Shape",parent=jot)
        mc.setAttr(con.lAttr(jot,"radius"),scale)
        
        mc.connectAttr(con.lAttr(jot,"radius"),con.lAttr(loc,"lsx"))
        mc.connectAttr(con.lAttr(jot,"radius"),con.lAttr(loc,"lsy"))
        mc.connectAttr(con.lAttr(jot,"radius"),con.lAttr(loc,"lsz"))

        if colorId:
            con.changColor(jot,colorId)
            con.changColor(loc,colorId)
        
        if crv:
            crvShape = con.findRelatedShape(crv)
            poci = mc.createNode(ntc.tPointOnCurveInfo, name=con.lname(name, sc.sPoci))
            mc.connectAttr(crvShape + ".ws[0]", poci + ".ic")
            mc.setAttr(poci + ".top", top)
            # mc.setAttr(poci + ".pr", parameter)
            mc.connectAttr(poci + ".p", jot + ".t")
            
            # maxValue = 100
            mc.addAttr(jot,ln="parameter",at="float",dv=0,min=0,max=maxValue,k=True)
            md = mc.createNode(ntc.tMultiplyDivide,name=con.lname(name,sc.sMd))
            mc.connectAttr(jot+".parameter",md+".i1x")
            mc.setAttr(md+".op",2)
            if top:
                mc.setAttr(md+".i2x",maxValue)
                mc.addAttr(jot+".parameter",e=True,dv = parameter*maxValue)
                mc.setAttr(jot + ".parameter", parameter*maxValue)
            else:
                print parameter
                mc.setAttr(md + ".i2x", 1)
                mc.addAttr(jot + ".parameter", e=True, dv=parameter)
                mc.setAttr(jot + ".parameter", parameter)
            mc.connectAttr(md+".ox",poci + ".pr")

        return jot
    
    def select_to_jloc(self,name,colorId=None,scale=0.1,crv = None,parameter=0,maxValue=100,top=True):
        
        sel = mc.ls(sl=True)
        clu = mc.cluster(sel)[1]
        x,y,z = mc.xform(clu,q=True,rp=True)
        _jloc = self.jloc(name,colorId=colorId,scale=scale,crv = crv,parameter=parameter,maxValue=maxValue,top=top)
        mc.setAttr(_jloc+".t",x,y,z)
        mc.delete(clu)
        return _jloc

    def mult_locOnCrv(self, name, number, crv, colorId):
        
        
        _old = mc.ls(con.lname(name,sc.sGrp))
        if _old:
            mc.delete(_old)
        grp = mc.createNode(ntc.tTransform,name = con.lname(name,sc.sGrp))
        mc.parent(grp,self.local_doDelete)
        crvShape = con.findRelatedShape(crv)
        for i in range(1,number+1,1):
            
            loc = mc.spaceLocator(name=con.lname(name, i, sc.sLoc))[0]
            poci = mc.createNode(ntc.tPointOnCurveInfo, name=con.lname(name, i, sc.sPoci))
            mc.connectAttr(crvShape + ".ws", poci + ".ic")
            mc.setAttr(poci + ".top", 1)
            parameter = (1. / (number - 1)) * (i-1)
            mc.setAttr(poci + ".pr", parameter)
            mc.connectAttr(poci + ".p", loc + ".t")
        
            mc.addAttr(loc, ln=ac.offset, at="float", dv=parameter * 100, k=True, min=0, max=100)
            offset_mdl = mc.createNode(ntc.tMultDoubleLinear, name=con.lname(name, i, sc.sMdl))
            mc.connectAttr(con.lAttr(loc, ac.offset), offset_mdl + ".i1")
            mc.setAttr(offset_mdl + ".i2", 0.01, l=True)
            mc.connectAttr(offset_mdl + ".o", poci + ".pr")
        
            con.lockHideAttr(loc)
            con.changColor(loc, colorId)
            mc.setAttr(con.findRelatedShape(loc)+".localScale",0.01,0.01,0.01)
            mc.parent(loc,grp)
        return
    
class BrowTemplate(FacialTemplate):
    def __init__(self):
        super(BrowTemplate,self).__init__(tag="tmp_"+fc.brow)
    
    
    def brow_mainCrv(self):

        lname = con.lname("tmp",fc.brow,)
        crvGrp = mc.createNode(ntc.tTransform, name=con.lname(lname, sc.sCrv), parent=self.local_doDelete, ss=True)
        mainCrv = con.lname(fc.lf,lname,fc.main,sc.sCrv)
        if mc.objExists(mainCrv):
            pass
        ptc = mc.polyToCurve(form= 2 ,degree =1)[0]
        mc.delete(ptc,ch=True)
        mc.rename(ptc,mainCrv)
        
        rmain_crv = con.mirrorCurve(mainCrv,mainCrv.replace(fc.lf,fc.rt))
        mc.parent(mainCrv,rmain_crv,crvGrp)

        for lr in [fc.lf,fc.rt]:
            crv = con.lname(lr,lname,fc.main,sc.sCrv)
            upCrv = con.lname(crv,fc.up)
            mc.duplicateCurve(crv,name=upCrv,ch=False)
    
            loCrv= con.lname(crv,fc.lo)
            mc.duplicateCurve(crv,name=loCrv,ch=False)
    
            mc.parent(upCrv,loCrv,crv)
            con.changColor(crv, 13)
            con.changColor(upCrv,18)
            con.changColor(loCrv,18)

            mc.xform(crv, cp=1)
            mc.xform(upCrv, cp=1)
            mc.xform(loCrv, cp=1)
            piv = mc.xform(loCrv, q=1, piv=1, os=1)[:3]
            cvs = mc.ls(loCrv+".cv[*]",fl=True)
            mc.scale(1,0,1,cvs,p=piv,r=True)

            ul_offest = con.lname(fc.up + fc.lo, ac.offset)
            mc.addAttr(crv,ln = ul_offest,at="float",dv=30,min=10,k=True)

            ud_md = mc.createNode(ntc.tMultiplyDivide,name= con.lname(lname,fc.up+fc.lo,sc.sMd))
            mc.connectAttr(con.lAttr(crv,ul_offest),con.lAttr(ud_md,"i1x"))
            mc.connectAttr(con.lAttr(crv,ul_offest),con.lAttr(ud_md,"i1y"))

            pro = 100.
            mc.setAttr(con.lAttr(ud_md,"i2x"),1/pro)
            mc.setAttr(con.lAttr(ud_md,"i2y"),-1/pro)

            mc.connectAttr(con.lAttr(ud_md,"ox"),con.lAttr(upCrv,"ty"))
            mc.connectAttr(con.lAttr(ud_md,"oy"),con.lAttr(loCrv,"ty"))
            
            control_point_tag = [fc.inn,fc.mid,fc.out]
            for i,cpt in enumerate(control_point_tag):
                ptj = self.jloc(con.lname(lr,lname,cpt),crv=crv,parameter=i*0.5,colorId=20)
                mc.parent(ptj,crvGrp)
            sup_jl = self.jloc(con.lname(lr, lname, fc.inn+"Sup"), crv=crv, parameter=0.2, colorId=21,scale=0.05)
            mc.parent(sup_jl, crvGrp)
            
            max_jl = self.jloc(name=con.lname(lr,lname,fc.inn+"Max"),scale=0.075,colorId=21)
            mc.parent(max_jl,con.lname(lr,lname,fc.inn))
            con.channelAttrToDefault(max_jl)
            mc.addAttr(max_jl, ln=ac.offset, at="float", dv=10, k=True, min=0)
            con.emptyGroup(max_jl)
            
            max_mdl = mc.createNode(ntc.tMultDoubleLinear,name = con.lname(lr,lname,fc.inn+"Max",sc.sMdl))
            mc.connectAttr(con.lAttr(max_jl, ac.offset), max_mdl + ".i1")
            if lr == fc.lf:
                mc.setAttr(max_mdl+".i2",-.01,l=True)
            else:
                mc.setAttr(max_mdl+".i2",.01,l=True)
            mc.connectAttr(max_mdl+".o",max_jl+".tx")

            

        return
        
    def brow_slider(self):
        
        lname = con.lname("tmp",fc.brow,"slider")
        crvGrp = mc.createNode(ntc.tTransform, name=con.lname(lname, sc.sCrv), parent=self.local_doDelete, ss=True)
        mainCrv = con.lname(lname,fc.main,sc.sCrv)
        if mc.objExists(mainCrv):
            pass
        ptc = mc.polyToCurve(form=2, degree=1)[0]
        mc.delete(ptc, ch=True)
        mc.rename(ptc, mainCrv)
        
        mel.eval('rebuildCurve -ch 0 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 0 -kep 1 -kt 0 -s 9 -d 1 -tol 0.01 "%s";'%mainCrv)
        mc.xform(mainCrv,cp=True)
        piv = mc.xform(mainCrv, q=1, piv=1, os=1)[:3]
        cvs = mc.ls(mainCrv+".cv[*]",fl=1)
        mc.scale(1,0,1,cvs,p=piv,r=True)
        
        con.changColor(mainCrv,17)
        xv = mc.getAttr(mainCrv+".cv[0].xv")
        zv = mc.getAttr(mainCrv+".cv[0].zv")
        mc.setAttr(mainCrv+".cv[0].zv",zv+xv)
        mc.setAttr(mainCrv+".cv[%s].zv"%(len(cvs)-1),zv+xv)
        mel.eval('rebuildCurve -ch 0 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 0 -kep 1 -kt 0 -s 8 -d 1 -tol 0.01 "%s";'%mainCrv)
        mel.eval('rebuildCurve -ch 0 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 1 -kep 1 -kt 0 -s 8 -d 3 -tol 0.01 "%s";'%mainCrv)
        
        # mainCrvShape = con.findRelatedShape(mainCrv)
        # for lr in [fc.lf,fc.rt]:
        #     mjl = con.lname(lr,"tmp_Brow_inner")
        #     # par = con.getObjInCrvParameter(mainCrv, con.lname(lr,"tmp_Brow_inner"))
        #     ptj = self.jloc(con.lname(lr, lname,fc.inn+"Max"),crv = mainCrv, colorId=20,scale=0.05,)
        #     mc.parent(ptj,mjl)
        #     mc.addAttr(ptj,ln="offest",at="float",dv=3,k=True,min=0)
        #
        #     npoc = mc.createNode(ntc.tNearestPointOnCurve,name = con.lname(lr,lname,sc.sNpoc))
        #     mc.connectAttr(mainCrvShape+".ws",npoc+".ic")
        #     mc.connectAttr(mjl+".t",npoc+".ip")
        #
        #     abs_mdl = mc.createNode(ntc.tMultDoubleLinear,name = con.lname(lr,lname,sc.sMdl))
        #     mc.connectAttr(ptj+'.offest',abs_mdl+".i1")
        #     if lr == fc.lf:
        #         mc.setAttr(abs_mdl+".i2",-1,l=True)
        #     else:
        #         mc.setAttr(abs_mdl+".i2",1,l=True)
        #
        #     pro_mdl = mc.createNode(ntc.tMultDoubleLinear,name=con.lname(lr,lname,sc.sMdl))
        #     mc.connectAttr(npoc+".pr",pro_mdl+".i1")
        #     mc.setAttr(pro_mdl+".i2",100)
        #
        #     adl = mc.createNode(ntc.tAddDoubleLinear,name = con.lname(lr,lname,sc.sAdl))
        #     mc.connectAttr(pro_mdl+".o",adl+".i1")
        #     mc.connectAttr(abs_mdl+".o",adl+".i2")
        #     mc.connectAttr(adl+".o",ptj+".parameter")
        #     mc.parent(ptj, crvGrp)

        mc.parent(mainCrv,crvGrp)
        return
    
class EyeTemplate(FacialTemplate):
    def __init__(self):
        super(EyeTemplate,self).__init__(tag=con.lname("tmp",fc.eye))
        
    def eyeball_center(self):
        
        center_jl = self.select_to_jloc(con.lname(fc.lf,"tmp",con.selfFuncName()),colorId=21)
        # print center_jl
        x, y, z = mc.xform(center_jl,q=True,ws=True,t=True)

        rt = self.jloc(name = center_jl.replace(fc.lf,fc.rt),colorId=21)
        mc.parent(center_jl,rt,self.local_doDelete,)
        mc.setAttr(rt+".t",-x,y,z)
        con.emptyGroup(center_jl,["Zero"])
        rtGrp = con.emptyGroup(rt,["Zero"])[0]
        con.localMirror(rtGrp)
        
        # mc.setAttr(rt)
        return

    def eyeball_aim(self):
        for lr in [fc.lf,fc.rt]:
            center_jl = con.lname(lr,"tmp","eyeball_center")
            aim_jl = con.lname(fc.lf,"tmp", con.selfFuncName())
            if not mc.objExists(aim_jl):
                self.select_to_jloc(aim_jl,colorId=21)
                mc.parent(aim_jl, center_jl)
                con.emptyGroup(aim_jl, ["Zero"])
            else:
                rt = self.jloc( name=aim_jl.replace(fc.lf, fc.rt),colorId=21)
                x, y, z = mc.xform(aim_jl,q=True,ws=True,t=True)
                mc.setAttr(rt + ".t", -x, y, z)
                rtGrp = con.emptyGroup(rt, ["Zero"])[0]
                mc.parent(rtGrp, center_jl,)
        return
    
    def eyelid_inn(self):
        eyelid_jl = self.select_to_jloc(con.lname(fc.lf,"tmp",fc.eyelid,fc.inn),colorId=20)
        rt = self.jloc(name=eyelid_jl.replace(fc.lf, fc.rt),colorId=20)
        x, y, z = mc.xform(eyelid_jl, q=True, ws=True, t=True)
        mc.setAttr(rt + ".t", -x, y, z)
        mc.parent(eyelid_jl, rt, self.local_doDelete)
        con.emptyGroup(eyelid_jl, ["Zero"])
        rtGrp = con.emptyGroup(rt, ["Zero"])[0]
        con.localMirror(rtGrp)
        return
    
    def eyelid_setting(self):
        
        for lr in [fc.lf,fc.rt]:
            self.eyelid_out(lr)
        return
    
    def eyelid_out(self,prefix):
        lname = con.lname(prefix,"tmp",fc.eyelid)
        center_jl = con.lname(prefix,"tmp","eyeball_center")
        eyelidInn_jl = con.lname(prefix,"tmp",fc.eyelid,fc.inn)
        _eyelidOut_jl = con.lname(fc.lf,"tmp",fc.eyelid,fc.out)
        # print _eyelidOut_jl
        if prefix == fc.lf:
            eyelidOut_jl = self.select_to_jloc(_eyelidOut_jl,colorId=20)
            # x,y,z = mc.xform(_eyelidOut_jl ,q=True,ws=True,t=True)
            # print x,y,z
            mc.parent(eyelidOut_jl,self.local_doDelete)
            con.emptyGroup(eyelidOut_jl, ["Zero"])
        else:
            x,y,z = mc.xform(_eyelidOut_jl ,q=True,ws=True,t=True)
            # print x,y,z
            rt = self.jloc(_eyelidOut_jl.replace(fc.lf, fc.rt),colorId=20)
            # rt = mc.duplicate(_eyelidOut_jl, name=_eyelidOut_jl.replace(fc.lf, fc.rt))[0]
            mc.setAttr(rt + ".t", -x,y,z)
            eyelidOut_jl = rt
            mc.parent(eyelidOut_jl,self.local_doDelete)
            rtGrp = con.emptyGroup(rt, ["Zero"])[0]
            con.localMirror(rtGrp)

        eyelidInn_jot = con.objToType(eyelidInn_jl,name = con.lname(eyelidInn_jl,sc.sJot),typ=ntc.tJoint)
        eyelidOut_jot = con.objToType(eyelidOut_jl,name = con.lname(eyelidOut_jl,sc.sJot),typ=ntc.tJoint)

        mc.parent(eyelidOut_jot,eyelidInn_jot)
        con.jointOrient([eyelidOut_jot,eyelidInn_jot])
        io_ikh = mc.ikHandle(sj=eyelidInn_jot,ee=eyelidOut_jot,sol="ikSCsolver")[0]
        mc.parent(eyelidInn_jot,eyelidInn_jl)
        mc.parent(io_ikh,eyelidOut_jl)
        
        mid_loc = mc.spaceLocator(name=con.lname(lname,fc.mid))[0]
        mc.parent(mid_loc,eyelidInn_jot)
        con.channelAttrToDefault(mid_loc)
        
        mid_dis = mc.createNode(ntc.tDistanceBetween,name = con.lname(lname,fc.mid,sc.sDbn))
        mc.connectAttr(con.findRelatedShape(eyelidInn_jl) + ".wp", mid_dis + ".p1")
        mc.connectAttr(con.findRelatedShape(eyelidOut_jl) + ".wp", mid_dis + ".p2")

        mid_mdl = mc.createNode(ntc.tMultDoubleLinear,name = con.lname(mid_loc,sc.sMdl))
        mc.connectAttr(mid_dis+".d",mid_mdl+".i1")
        mc.setAttr(mid_mdl+".i2",0.5,l=True)
        mc.connectAttr(mid_mdl+".o",mid_loc+".tx")
        
        mid_center_jl = self.jloc(name=con.lname(lname,"center","aim"))
        mc.delete(mc.pointConstraint(center_jl,mid_center_jl,mo=False))
        mid_jl = self.jloc(name=con.lname(lname,fc.mid,"aim"))
        mc.delete(mc.pointConstraint(mid_loc,mid_jl,mo=False))
        mc.parent(mid_jl,mid_center_jl)
        con.jointOrient([mid_jl,mid_center_jl])
        
        mid_ikh = mc.ikHandle(sj=mid_center_jl,ee=mid_jl,sol="ikSCsolver")[0]
        mc.parent(mid_ikh,mid_loc)
        con.channelAttrToDefault(mid_ikh)

        dis_inn = mc.createNode(ntc.tDistanceBetween,name = con.lname(lname,fc.inn,sc.sDbn))
        mc.connectAttr(con.findRelatedShape(center_jl)+".wp",dis_inn+".p1")
        mc.connectAttr(con.findRelatedShape(eyelidInn_jl)+".wp",dis_inn+".p2")
        
        dis_out = mc.createNode(ntc.tDistanceBetween,name = con.lname(lname,fc.out,sc.sDbn))
        mc.connectAttr(con.findRelatedShape(center_jl)+".wp",dis_out+".p1")
        mc.connectAttr(con.findRelatedShape(eyelidOut_jl)+".wp",dis_out+".p2")
        
        dis_adl = mc.createNode(ntc.tAddDoubleLinear,name = con.lname(lname,"distance",sc.sAdl))
        mc.connectAttr(dis_inn+".d",dis_adl+".i1")
        mc.connectAttr(dis_out+".d",dis_adl+".i2")
        
        dis_mdl = mc.createNode(ntc.tMultDoubleLinear,name = con.lname(lname,"distance",sc.sMdl))
        mc.connectAttr(dis_adl+".o",dis_mdl+".i1")
        mc.setAttr(dis_mdl+".i2",0.5)

        _tmp_center_crv = mc.rename(mc.curve(p=[0,0,0],d=1))
        center_crv = mc.rename(_tmp_center_crv,con.lname(lname,fc.cr,sc.sCrv))
        mtpc = mc.createNode(ntc.tMakeThreePointCircularArc,name = con.lname(center_crv,sc.sMtpca))
        mc.connectAttr(con.findRelatedShape(eyelidInn_jl) + ".wp",mtpc+".pt1")
        mc.connectAttr(con.findRelatedShape(mid_jl) + ".wp",mtpc+".pt2")
        mc.connectAttr(con.findRelatedShape(eyelidOut_jl) + ".wp",mtpc+".pt3")
        mc.connectAttr(mtpc+".oc",con.findRelatedShape(center_crv)+".create")
        con.changColor(center_crv,18)
        
        heightOffset = "radiusOffset"
        mc.addAttr(center_crv, ln=heightOffset, at="float", dv=0, k=True)
        r_offset_mdl = mc.createNode(ntc.tMultDoubleLinear, name=con.lname(center_crv, heightOffset, sc.sMdl))
        mc.connectAttr(con.lAttr(center_crv, heightOffset), r_offset_mdl + ".i1")
        mc.setAttr(r_offset_mdl + ".i2", 0.01)

        r_offset_adl = mc.createNode(ntc.tAddDoubleLinear, name=con.lname(center_crv, heightOffset, sc.sAdl))
        mc.connectAttr(r_offset_mdl + ".o", r_offset_adl + ".i1")
        mc.connectAttr(dis_mdl + ".o", r_offset_adl + ".i2")
        # mc.connectAttr(r_offset_adl+".o",dis_mdl+".i2",f=True)
        mc.connectAttr(r_offset_adl+".o",mid_jl+".tx")

        uplid_crv = mc.duplicate(center_crv,name=con.lname(lname,fc.up,sc.sCrv),rr=True)[0]
        lolid_crv = mc.duplicate(center_crv,name=con.lname(lname,fc.lo,sc.sCrv),rr=True)[0]
        mc.setAttr(uplid_crv+".template",1)
        mc.setAttr(lolid_crv+".template",1)

        uplid_crv_offset = mc.group(em=True,name=con.lname(uplid_crv, ac.offset),parent=eyelidInn_jot)
        lolid_crv_offset = mc.group(em=True,name=con.lname(lolid_crv, ac.offset),parent=eyelidInn_jot)
        center_crv_offset = mc.group(em=True,name=con.lname(center_crv, ac.offset),parent=eyelidInn_jl)

        mc.parent(uplid_crv,uplid_crv_offset)
        mc.parent(lolid_crv,lolid_crv_offset)
        mc.parent(uplid_crv_offset,lolid_crv_offset,center_crv_offset)
        
        mc.blendShape(center_crv,uplid_crv,w=[0,1],name = con.lname(uplid_crv,"Bls"))
        mc.blendShape(center_crv,lolid_crv,w=[0,1],name = con.lname(lolid_crv,"Bls"))

        con.lockHideAttr(center_crv)
        heightOffset = "lid_heightOffset"
        mc.addAttr(center_crv,ln=heightOffset,at="float",dv=5,min=0.1,k=True)
        up_offset_md = mc.createNode(ntc.tMultiplyDivide,name=con.lname(center_crv,heightOffset))
        mc.connectAttr(con.lAttr(center_crv,heightOffset),up_offset_md+".i1x")
        mc.setAttr(up_offset_md+".i2x",0.01)
        mc.connectAttr(con.lAttr(center_crv,heightOffset),up_offset_md+".i1y")
        mc.setAttr(up_offset_md+".i2y",-0.01)
        mc.connectAttr(up_offset_md+".ox",uplid_crv_offset+".ty")
        mc.connectAttr(up_offset_md+".oy",lolid_crv_offset+".ty")
        
        heightOffset = "heightOffset"
        mc.addAttr(center_crv,ln=heightOffset,at="float",dv=0,k=True)
        up_offset_mdl = mc.createNode(ntc.tMultDoubleLinear,name=con.lname(center_crv,heightOffset))
        mc.connectAttr(con.lAttr(center_crv,heightOffset),up_offset_mdl+".i1")
        mc.setAttr(up_offset_mdl+".i2",0.01)
        mc.connectAttr(up_offset_mdl+".o",mid_loc+".ty")
        
        mc.hide(mid_ikh,io_ikh,eyelidInn_jot,mid_loc,mid_center_jl)
        mc.parent(center_crv,mid_center_jl,self.local_doDelete)
        
        # -- open max
        
        for ul in [fc.up,fc.lo]:
            rot = mc.createNode(ntc.tTransform,name = con.lname(lname,ul,"rot"))
            mc.delete(mc.pointConstraint(center_jl,rot,mo=False))
            rotGrp = con.emptyGroup(rot, ["Zero"])[0]
            #aimConstraint -offset 0 0 0 -weight 1 -aimVector 0 0 1 -upVector 1 0 0 -worldUpType "object" -worldUpObject locator3;
            mc.aimConstraint(mid_jl,rotGrp,aimVector=[0,0,1],upVector= [1,0,0],worldUpType ="object",worldUpObject=eyelidOut_jl)
            # mc.delete(mc.orientConstraint(eyelidInn_jot,rot,mo=False))
            mc.parent(rotGrp,self.local_doDelete)

            ul_mid_jl = self.jloc(name=con.lname(lname,ul+fc.mid,"aim"))
            mc.delete(mc.parentConstraint(rot,ul_mid_jl,mo=False))
            _mgl = con.emptyGroup(ul_mid_jl,["Zero"])[0]
            mc.parent(_mgl,rot)
            
            _mtpac = mc.createNode(ntc.tMakeThreePointCircularArc,name=con.lname(lname,ul,sc.sMtpca))
            mc.connectAttr(con.findRelatedShape(eyelidInn_jl)+".wp",_mtpac+".pt1")
            mc.connectAttr(con.findRelatedShape(ul_mid_jl)+".wp",_mtpac+".pt2")
            mc.connectAttr(con.findRelatedShape(eyelidOut_jl)+".wp",_mtpac+".pt3")
            
            ul_crv = mc.rename(mc.curve(p=[0,0,0],d=1),con.lname(lname,ul,"openMax",sc.sCrv))
            mc.connectAttr(_mtpac+".oc",con.findRelatedShape(ul_crv)+".create")
            
            _attr = con.lname("openRadius")
            mc.addAttr(ul_crv,ln=_attr,at="float",dv=0.05,min=0,k=True)
            openMax_adl = mc.createNode(ntc.tAddDoubleLinear,name = con.lname(lname,ul,sc.sAdl))
            mc.connectAttr(dis_mdl+".o",openMax_adl+".i1")
            mc.connectAttr(con.lAttr(ul_crv,_attr),openMax_adl+".i2")
            mc.connectAttr(openMax_adl + ".o", _mgl + ".tz")
            
            _attr = con.lname("openMax")
            mc.addAttr(ul_crv,ln=_attr,at="float",dv=30,min=0,k=True)
            openMax_mdl = mc.createNode(ntc.tMultDoubleLinear,name = con.lname(lname,ul,sc.sMdl))
            mc.connectAttr(con.lAttr(ul_crv,_attr),openMax_mdl+".i1")

            if prefix == fc.lf:
                if ul == fc.up:
                    mc.setAttr(openMax_mdl+".i2",-1,l=True)
                else:
                    mc.setAttr(openMax_mdl+".i2",1,l=True)
            else:
                if ul == fc.up:
                    mc.setAttr(openMax_mdl+".i2",1,l=True)
                else:
                    mc.setAttr(openMax_mdl+".i2",-1,l=True)
            mc.connectAttr(openMax_mdl + ".o", rot + ".rx")

            con.lockHideAttr(ul_crv)
            con.changColor(ul_crv,18)
            mc.hide(rot)
            mc.parent(ul_crv,self.local_doDelete)
        
        return

    def eyelid_skin(self, number=10):
        
        for lr in [fc.lf,fc.rt]:
            for tag in [fc.up,fc.lo]:
                lid_crv = con.lname(lr,"tmp", fc.eyelid, tag, sc.sCrv)
                self.mult_locOnCrv(con.lname(lr,"tmp",fc.eyelid,tag,"skin"),number,lid_crv,4)

        return

    def eyelid_ctrl(self, number=10):

        for tag in [fc.lf,fc.rt]:
            lid_crv = con.lname(tag,"tmp", fc.eyelid,fc.cr, sc.sCrv)
            self.mult_locOnCrv(con.lname(tag,fc.eyelid,fc.cr,"ctrl"), number, lid_crv, 27)

        return
    
    def eyeSocket_line(self, tag=fc.up):
        
        _nn = con.lname(fc.eyeSocket,"tmp",tag,sc.sCrv)
        crv = mc.rename(mc.polyToCurve(form= 2 ,degree =1)[0],con.lname(fc.lf,_nn))
        rt_crv = con.copyCurve(crv,con.lname(fc.rt,_nn))
        con.localMirror(rt_crv,"world")
        mc.makeIdentity(rt_crv,apply=True)
        
        mc.parent(crv,rt_crv,self.local_doDelete)
        mc.delete(crv,rt_crv,ch=True)
        mel.eval('rebuildCurve -ch 0 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 0 -kep 1 -kt 0 -s 6 -d 3 -tol 0.01 "%s";'%crv)
        mel.eval('rebuildCurve -ch 0 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 0 -kep 1 -kt 0 -s 6 -d 3 -tol 0.01 "%s";'%rt_crv)
        
        con.changColor(crv,28)
        con.changColor(rt_crv,28)

        return
    def eyeSocket_number(self,number):
        for lr in [fc.lf, fc.rt]:
            for ul in [fc.up,fc.lo]:
                crv = con.lname(lr, fc.eyeSocket,"tmp",ul,sc.sCrv)
                self.mult_locOnCrv(con.lname(lr, fc.eyeSocket,"tmp",ul), number, crv=crv, colorId=21)
        
        return
    
class MouthTemplate(FacialTemplate):
    def __init__(self):
        super(MouthTemplate,self).__init__(tag="tmp_"+fc.mouth)
    
    def jaw_point(self):
        _jaw = con.lname("tmp",fc.jaw)
        if mc.objExists(_jaw):
            mc.delete(_jaw)
        center_jl = self.select_to_jloc(con.lname("tmp",fc.jaw),colorId=16)
        mc.setAttr(center_jl+".tx",0)
        mc.parent(center_jl,self.local_doDelete)
        # con.changColor()
        return
    
    def lip_curve(self,tag):
        lname = con.lname(fc.mouth,"tmp",tag,fc.lip,)
        ptc = mc.rename(mc.polyToCurve(form= 2 ,degree =1)[0],con.lname(lname,sc.sCrv))
        con.changColor(ptc,13)
        mc.parent(ptc,self.local_doDelete)
        
        cvs = len(mc.ls(ptc+".cv[*]",fl=True))-1
        pt1 = mc.xform(ptc+".cv[0]",q=True,ws=True,t=True)[0]
        pt2 = mc.xform(ptc+".cv[%s]"%cvs,q=True,ws=True,t=True)[0]
        if pt2>pt1:
            mc.reverseCurve(ptc,ch=False)
        mc.delete(ptc, ch=True)
        mel.eval(
            'rebuildCurve -ch 0 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 0 -kep 1 -kt 0 -s 8 -d 3 -tol 0.01 "%s";' % ptc)

        return
    
    def lip_skin_number(self,number=10):
        
        for ul in [fc.up,fc.lo]:
            lid_crv = con.lname(fc.mouth, "tmp", ul,fc.lip, sc.sCrv)
            self.mult_locOnCrv(con.lname(fc.mouth, "tmp", ul,fc.lip, "skin"), number, lid_crv, 20)
            # self.mult_locOnCrv()
        
        return

    def lip_ctrl_number(self, number=10):
    
        for ul in [fc.up, fc.lo]:
            lid_crv = con.lname(fc.mouth, "tmp", ul, fc.lip, sc.sCrv)
            self.mult_locOnCrv(con.lname(fc.mouth, "tmp", ul, fc.lip, "ctrl"), number, lid_crv, 19)
            # self.mult_locOnCrv()
    
        return
    
    def lip_slider(self):
        
        lname = con.lname(fc.mouth,"tmp", fc.lip, "slider")
        # crvGrp = mc.createNode(ntc.tTransform, name=con.lname(lname, sc.sCrv), parent=self.local_doDelete, ss=True)
        mainCrv = con.lname(lname, fc.main, sc.sCrv)
        if mc.objExists(mainCrv):
            mc.delete(mainCrv)
        ptc = mc.rename(mc.duplicate(con.lname(fc.mouth,"tmp",fc.up,fc.lip,sc.sCrv))[0],mainCrv)
        mc.delete(ptc, ch=True)
        # mc.rename(ptc, mainCrv)
    
        mel.eval('rebuildCurve -ch 0 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 0 -kep 1 -kt 0 -s 9 -d 1 -tol 0.01 "%s";' % mainCrv)
        mc.xform(mainCrv, cp=True)
        piv = mc.xform(mainCrv, q=1, piv=1, os=1)[:3]
        cvs = mc.ls(mainCrv + ".cv[*]", fl=1)
        mc.scale(1, 0, 1, cvs, p=piv, r=True)
    
        con.changColor(mainCrv, 17)
        xv = mc.getAttr(mainCrv + ".cv[0].xv")
        zv = mc.getAttr(mainCrv + ".cv[0].zv")
        # print xv,zv
        mc.setAttr(mainCrv + ".cv[0].zv", zv-xv)
        mc.setAttr(mainCrv + ".cv[%s].zv" % (len(cvs) - 1), zv-xv)
        mel.eval('rebuildCurve -ch 0 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 0 -kep 1 -kt 0 -s 8 -d 1 -tol 0.01 "%s";' % mainCrv)
        mel.eval('rebuildCurve -ch 0 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 1 -kep 1 -kt 0 -s 8 -d 3 -tol 0.01 "%s";' % mainCrv)
        
        # mc.parent(mainCrv,self.local_doDelete)
        
        up_tmp_crv = con.lname(fc.mouth,"tmp",fc.up,fc.lip,sc.sCrv)
        lo_tmp_crv = con.lname(fc.mouth,"tmp",fc.lo,fc.lip,sc.sCrv)

        cvs = mc.ls(up_tmp_crv+".cv[*]",fl=True)
        max_v = len(cvs)-1
        x, y, z = mc.xform(up_tmp_crv + ".cv[0]", q=True,ws=True,t=True)
        ptcShape = con.findRelatedShape(ptc)
        for lr in [fc.lf,fc.rt]:
            _jl = self.jloc(name=con.lname(lr,"tmp",fc.corner,),colorId=17)
            _ul_max = self.jloc(name=con.lname(lr,"tmp",fc.corner,fc.ul+"Max"),colorId=18)
            _lr_max = self.jloc(name=con.lname(lr,"tmp",fc.corner,fc.lr+"Max"),colorId=18)
            mc.parent(_ul_max,_lr_max,_jl)
            mc.setAttr(_ul_max+".ty",0.1)
            mc.setAttr(_lr_max+".tx",0.1)
            mc.parent(_jl,self.local_doDelete)
            grp = con.emptyGroup(_jl)
            _jlShape = con.findRelatedShape(_jl)
            mc.setAttr(_jl + ".t", x, y, z)
            if lr == fc.lf:
                count = 0
            else:
                con.localMirror(grp[0])
                count = max_v

            mc.connectAttr(_jlShape + ".wp", up_tmp_crv + ".cp[%s]"%count)
            mc.connectAttr(_jlShape + ".wp", lo_tmp_crv + ".cp[%s]"%count)

            _lr_maxPt = self.jloc(name=con.lname(lr,"tmp",fc.corner,fc.lr+"MaxPoint",),colorId=21)
            nopc = mc.createNode(ntc.tNearestPointOnCurve,name = con.lname(_lr_max,sc.sNpoc))
            mc.connectAttr(con.findRelatedShape(_lr_max)+".wp",nopc+".ip")
            mc.connectAttr(ptcShape+".ws",nopc+".ic")
            mc.connectAttr(nopc+".p",_lr_maxPt+".t")
            mc.parent(_lr_maxPt,self.local_doDelete)
            

        
        return
    def mirror_offset(self):
        #Mouth_tmp_Up_Lip_ctrl_5_loc
        for ul in [fc.up,fc.lo]:
            for cs in ["ctrl","skin"]:
                tag = con.lname(fc.mouth,"tmp",ul,fc.lip,cs,"*",sc.sLoc)
                sel = mc.ls(tag)
                l = len(sel)
                for i in range(len(sel)):
                    v = mc.getAttr(con.lname(fc.mouth,"tmp",ul,fc.lip,cs,i+1,"loc.offset"))
                    mc.setAttr(con.lname(fc.mouth,"tmp",ul,fc.lip,cs,(l - i),"loc.offset") , 100 - v)
        return
class NoseTemplate(FacialTemplate):
    def __init__(self):
        super(NoseTemplate,self).__init__("tmp_"+fc.nose)
        
    def noseRoot(self):
        jl = self.select_to_jloc(name=con.lname("tmp",fc.nose,fc.root),colorId=21)
        mc.setAttr(jl+".tx",0)
        mc.parent(jl,self.local_doDelete)
        con.lockHideAttr(jl,["tx"])
        return
    def noseTip(self):
        jl = self.select_to_jloc(name=con.lname("tmp", fc.noseTip),colorId=20)
        mc.setAttr(jl + ".tx", 0)
        mc.setAttr(jl+".radius",0.08)
        con.lockHideAttr(jl,["tx"])
        jl_root = con.lname("tmp",fc.nose,fc.root)
        jr_y = mc.xform(jl_root,q=True,ws=True,t=True)
        j_y = mc.xform(jl,q=True,ws=True,t=True)
        
        dis = lambda a,b:pow(pow(a[0]-b[0],2)+pow(a[1]-b[1],2)+pow(a[2]-b[2],2),.5)
        _d = dis(jr_y,j_y)*.3
        for lr in [fc.lf,fc.rt]:
            lr_jl = self.jloc(name=con.lname(lr,"tmp",fc.noseAlar),colorId=20)
            mc.delete(mc.pointConstraint(jl,lr_jl,mo=False))
            mc.setAttr(lr_jl + ".tz", mc.getAttr(lr_jl + ".tz")-_d)
            if lr == fc.lf:
                mc.setAttr(lr_jl+".tx",_d)
            else:
                mc.setAttr(lr_jl+".tx",-_d)
            mc.parent(lr_jl, jl)
            mc.setAttr(lr_jl + ".radius", 0.05)

        mc.parent(jl,jl_root)

        return
class EarTemplate(FacialTemplate):
    def __init__(self):
        super(EarTemplate,self).__init__("tmp_"+fc.ear)
        
    def earRoot(self):
        
        jl = self.select_to_jloc(name=con.lname(fc.lf,"tmp",fc.earRoot),colorId=20)
        # mc.setAttr(jl+".tx",0)
        x, y, z = mc.xform(jl,q=True,ws=True,t=True)

        rt = self.jloc(name=jl.replace(fc.lf, fc.rt),colorId=20)
        # jl = mc.duplicate(jl,name=con.lname(fc.rt,"tmp",fc.earRoot))
        # mc.parent(jl,self.local_doDelete)
        # con.localMirror(jl,"world")
        mc.setAttr(rt+".t",-x,y,z)
        mc.parent(jl,rt,self.local_doDelete)
        con.emptyGroup(jl, ["Zero"])
        rtGrp = con.emptyGroup(rt, ["Zero"])[0]
        con.localMirror(rtGrp,)
        return
    
    def earEnd(self):
        
        for lr in [fc.lf,fc.rt]:
            if lr ==  fc.lf:
                jl = self.select_to_jloc(name=con.lname(lr,"tmp",fc.ear),colorId=20)
                con.emptyGroup(jl, ["Zero"])

            else:
                x, y, z = mc.xform(jl, q=True, ws=True, t=True)
                jl = self.jloc(name=jl.replace(fc.lf, fc.rt),colorId=20)
                mc.setAttr(jl + ".t", -x, y, z)
                rtGrp = con.emptyGroup(jl, ["Zero"])[0]

                con.localMirror(rtGrp,)

            jlroot = con.lname(lr,"tmp",fc.earRoot)
            mc.parent(jl,jlroot)
            
            pts = [mc.xform(_,q=True,ws=True,t=True) for _ in [jlroot,jl]]
            # print mc.curve(p=pts,d=1)
            _crv = mc.rename(mc.curve(p=pts,d=1),con.lname(lr,fc.ear,sc.sCrv))
            con.changColor(_crv,15)
            mc.parent(_crv,self.local_doDelete)
            for i,_j in enumerate([jlroot,jl]):
                loc = con.findRelatedShape(_j)
                mc.connectAttr(loc+".wp",_crv+".cp[%s]"%i)
        self.earNumber()
        return
    
    def earNumber(self,number=2):
        
        for lr in [fc.lf,fc.rt]:
            crv = con.lname(lr, fc.ear, sc.sCrv)
            self.mult_locOnCrv(con.lname(lr,fc.ear),number,crv=crv,colorId=18)
        
        return

class TongueTemplate(FacialTemplate):
    def __init__(self):
        super(TongueTemplate,self).__init__("tmp_"+fc.tongue)

    def import_template(self):
        pt = mc.xform(con.lname(fc.facial, sc.sJot), q=True, ws=True, t=True)
        pt2 = pt[0],pt[1],pt[2]+2
        crv = mc.rename(mc.curve(p=[pt,pt2],d=1),con.lname(fc.tongue,"tmp",sc.sCrv))
        mel.eval('rebuildCurve -ch 0 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 0 -kep 1 -kt 0 -s 3 -d 2 -tol 0.01 "%s";' % crv)
        con.changColor(crv,21)
        mc.parent(crv,self.local_doDelete)
        return
    def tongueNumber(self,number=5):
        crv = con.lname(fc.tongue,"tmp",sc.sCrv)
        mel.eval('rebuildCurve -ch 0 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 0 -kep 1 -kt 0 -s 0 -d 2 -tol 0.01 "%s";' % crv)

        self.mult_locOnCrv(con.lname(fc.tongue,"tmp"), number,
                           crv=crv, colorId=18)
        
        return
class StretchTemplate(FacialTemplate):
    def __init__(self):
        super(StretchTemplate,self).__init__("tmp_"+fc.stretch)
        
    def import_template(self):
        
        x,y,z = mc.xform(con.lname(fc.facial,sc.sJot),q=True,ws=True,t=True)
        jl = self.jloc(con.lname(fc.stretch,fc.up,fc.root),colorId=21)
        mc.parent(jl,self.local_doDelete)
        mc.setAttr(jl+".t",x,y,z)
        jl1 = self.jloc(con.lname(fc.stretch,fc.up,1),colorId=21)
        mc.parent(jl1,jl,r=True)
        mc.setAttr(jl1+".ty",1)
        jl2 = self.jloc(con.lname(fc.stretch,fc.up,2),colorId=21)
        mc.parent(jl2,jl1,r=True)
        mc.setAttr(jl2+".ty",1)
        
        for _j in [jl,jl1,jl2]:
            con.lockHideAttr(_j,ignore=["ty","tz"])

        return
    
    
    
if __name__ == '__main__':
    pass